/*
 * Copyright 2010 Facebook, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.android;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.facebook.android.Facebook.DialogListener;
import com.gt.common.view.OhProgressDialog;
import com.gt.facebook.FacebookManager;
import com.gt.facebook.ResourceManager;

public class FbDialog extends Dialog implements DialogInterface.OnDismissListener {

	private static final String TAG = "FbDialog";
	static final int FB_BLUE = 0xFF6D84B4;
	static final float[] DIMENSIONS_DIFF_LANDSCAPE = { 20, 60 };
	static final float[] DIMENSIONS_DIFF_PORTRAIT = { 40, 60 };
	static final FrameLayout.LayoutParams FILL = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
	static final int MARGIN = 4;
	static final int PADDING = 2;
	static final String DISPLAY_STRING = "touch";
	static final String FB_ICON = "icon.png";

	private String mUrl;
	private DialogListener mListener;
	private Dialog mSpinner;
	private ImageView mCrossImage;
	private WebView mWebView;
	private FrameLayout mContent;

	private boolean isPageFinishedComplete = false;

	private static int resIdTextLoading = 0;
	
	private static final String MESSAGE="Please wait. Loading...";

	public FbDialog(Context context, String url, DialogListener listener) {
		super(context, android.R.style.Theme_Translucent_NoTitleBar);
		mUrl = url;
		mListener = listener;
		
		if(FacebookManager.getInstance().isUseCustomProgressDialog()){
			mSpinner = new OhProgressDialog(getContext());
			((OhProgressDialog)mSpinner).setMessage(getContext().getResources().getText(resIdTextLoading, MESSAGE));
		}
		else{
			mSpinner=new ProgressDialog(getContext());
			((ProgressDialog)mSpinner).setMessage(getContext().getResources().getText(resIdTextLoading, MESSAGE));
			mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
			mSpinner.setCanceledOnTouchOutside(false);
		}

		mSpinner.setOnDismissListener(this);
		mSpinner.setOnCancelListener(new OnCancelListener() {
			
			@Override
			public void onCancel(DialogInterface dialog) {
				Log.d(TAG, "onProgressDialog oncanel...");
				if(mListener != null) {
					Log.d(TAG, "onProgressDialog oncanel>>> listener != null");
					mListener.onProgressDialogCancel();
				}
			}
		});
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		super.setCanceledOnTouchOutside(false);
		getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

		requestWindowFeature(Window.FEATURE_NO_TITLE);
		mContent = new FrameLayout(getContext());

		/*
		 * Create the 'x' image, but don't add to the mContent layout yet at this point, we only need to know its drawable width and height to place
		 * the webview
		 */
		createCrossImage();

		/*
		 * Now we know 'x' drawable width and height, layout the webivew and add it the mContent layout
		 */
		int crossWidth = mCrossImage.getDrawable().getIntrinsicWidth();
		setUpWebView(crossWidth / 2);

		/*
		 * Finally add the 'x' image to the mContent layout and add mContent to the Dialog view
		 */
		mContent.addView(mCrossImage, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
		addContentView(mContent, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
	}

	public static void setResIdTextLoading(int resId) {
		resIdTextLoading = resId;
	}

	private void createCrossImage() {
		mCrossImage = new ImageView(getContext());
		// Dismiss the dialog when user click on the 'x'
		mCrossImage.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				mListener.onCancel();
				FbDialog.this.dismiss();
			}
		});
		
		int closeDrawable = ResourceManager.getResource(ResourceManager.drawable_close, R.drawable.close);
		if(closeDrawable > 0) {
			Drawable crossDrawable = getContext().getResources().getDrawable(closeDrawable);
			mCrossImage.setImageDrawable(crossDrawable);
		}
		
		/*
		 * 'x' should not be visible while webview is loading make it visible only after webview has fully loaded
		 */
		mCrossImage.setVisibility(View.INVISIBLE);
	}

	private void setUpWebView(int margin) {
		LinearLayout webViewContainer = new LinearLayout(getContext());
		mWebView = new WebView(getContext());
		mWebView.setVerticalScrollBarEnabled(false);
		mWebView.setHorizontalScrollBarEnabled(false);
		mWebView.setWebViewClient(new FbDialog.FbWebViewClient());
		
		
		// mWebView.setWebChromeClient(new WebChromeClient(){
		//
		// });

		mWebView.getSettings().setJavaScriptEnabled(true);
		
		//{20120812,Try to make WebView loads login page correctly after switching network. （失败！）
		//顺便加快了检测能否连通facebook, 在GT3的情况下。  （失败！）
//		mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
//		mWebView.getSettings().setLoadWithOverviewMode(false);
//		mWebView.clearHistory();
////		mWebView.setSaveEnabled(false);
//		Log.i(TAG, "setUpWebView>>>>abc333");
		//}

		// {20120717
		Log.i(TAG, "setUpWebView>>>>sendEmptyMessageDelayed");
		isPageFinishedComplete = false;
		timeoutHandler.removeMessages(MSG_TIMEOUT);
		timeoutHandler.sendEmptyMessageDelayed(MSG_TIMEOUT, TIMEOUT_DELAY);
		// }

		mWebView.loadUrl(mUrl);
		mWebView.setLayoutParams(FILL);
		mWebView.setVisibility(View.INVISIBLE);

		webViewContainer.setPadding(margin, margin, margin, margin);
		
		int bgDrawable = ResourceManager.getResource(ResourceManager.drawable_dialogBackground, Color.BLACK);
		
		
		if(bgDrawable > 0) {
			webViewContainer.setBackgroundResource(bgDrawable);
		}
		
		webViewContainer.addView(mWebView);
		mContent.addView(webViewContainer);
	}

	private class FbWebViewClient extends WebViewClient {

		@Override
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			Log.i(TAG, "shouldOverrideUrlLoading>>>>url=" + url);
			Util.logd("Facebook-WebView", "Redirect URL: " + url);
			if (url.startsWith(Facebook.REDIRECT_URI)) {

				Log.i(TAG, "shouldOverrideUrlLoading>>>>REDIRECT_URI");

				Bundle values = Util.parseUrl(url);

				String error = values.getString("error");
				if (error == null) {
					error = values.getString("error_type");
				}

				if (error == null) {
					mListener.onComplete(values);
				} else if (error.equals("access_denied") || error.equals("OAuthAccessDeniedException")) {
					mListener.onCancel();
				} else {
					mListener.onFacebookError(new FacebookError(error));
				}

				FbDialog.this.dismiss();
				
				close();
				return true;
			} else if (url.startsWith(Facebook.CANCEL_URI)) {
				Log.i(TAG, "shouldOverrideUrlLoading>>>>CANCEL_URI");

				mListener.onCancel();
				FbDialog.this.dismiss();
				return true;
			} else if (url.contains(DISPLAY_STRING)) {

				// {20120716
				Log.i(TAG, "shouldOverrideUrlLoading>>>>DISPLAY_STRING sendEmptyMessageDelayed");
				isPageFinishedComplete = false;
				timeoutHandler.removeMessages(MSG_TIMEOUT);
				timeoutHandler.sendEmptyMessageDelayed(MSG_TIMEOUT, TIMEOUT_DELAY);
				// }

				return false;
			}

			// {20120717
			Log.i(TAG, "shouldOverrideUrlLoading>>>>ACTION_VIEW sendEmptyMessageDelayed");
			FbDialog.this.dismiss();
			close();
			isPageFinishedComplete = false;
			timeoutHandler.removeMessages(MSG_TIMEOUT);
			timeoutHandler.sendEmptyMessageDelayed(MSG_TIMEOUT, TIMEOUT_DELAY);
			// }

			// launch non-dialog URLs in a full browser
			getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
			return true;
		}

		@Override
		public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
			Log.i(TAG, "onReceivedError>>>>removeMessages FbDilaog:"+isShowing()+" progess dialog:"+mSpinner.isShowing());
			timeoutHandler.removeMessages(MSG_TIMEOUT);
			
			mListener.onError(new DialogError(description, errorCode, failingUrl));
//			mSpinner.dismiss();
			dismiss();
			
			super.onReceivedError(view, errorCode, description, failingUrl);
			
			close();
		}

		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			Util.logd("Facebook-WebView", "Webview loading URL: " + url);
			Log.i(TAG, "onPageStarted>>>>");
			super.onPageStarted(view, url, favicon);
			// isPageFinishedComplete=false;//
			mSpinner.show();
		}

		@Override
		public void onPageFinished(WebView view, String url) {
			Log.i(TAG, "onPageFinished>>>>removeMessages");
			isPageFinishedComplete = true;
			timeoutHandler.removeMessages(MSG_TIMEOUT);
			super.onPageFinished(view, url);
			mSpinner.dismiss();
			/*
			 * Once webview is fully loaded, set the mContent background to be transparent and make visible the 'x' image.
			 */
			mContent.setBackgroundColor(Color.TRANSPARENT);
			if(mWebView != null) {
				mWebView.setVisibility(View.VISIBLE);
			}
			mCrossImage.setVisibility(View.VISIBLE);
		}

	}

	// @Override
	// public void dismiss() {
	// if(mSpinner!=null && mSpinner.isShowing()){
	// mSpinner.dismiss();
	// }
	// super.dismiss();
	// }

	@Override
	public void onDismiss(DialogInterface dialog) {
		// Log.i(TAG, "onDismiss>>>>");
		if (!isPageFinishedComplete) {
			Log.i(TAG, "onDismiss>>>>removeMessages");
			timeoutHandler.removeMessages(MSG_TIMEOUT);
			if(mWebView != null) {
				try {
					mWebView.stopLoading();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			super.dismiss();
		}
	}
	
	private void close(){
		if(mWebView!=null&&mWebView.isShown()){
			try {
				mWebView.stopLoading();
				mWebView.clearCache(true);
				mWebView.destroy();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	 @Override
	 public boolean onKeyUp(int keyCode, KeyEvent event) {
	 if(event.getKeyCode()==KeyEvent.KEYCODE_BACK){
		Log.i(TAG, "onKeyUp:"+isShowing()+" progess dialog:"+mSpinner.isShowing());
	 }
	 return super.onKeyUp(keyCode, event);
	 }

	private static final long TIMEOUT_DELAY = 40 * 1000;
	private static final int MSG_TIMEOUT = 400;
	private Handler timeoutHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (msg.what == MSG_TIMEOUT) {
				Log.i(TAG, "handleMessage>>>>MSG_TIMEOUT");
				if(mWebView != null) {
					mWebView.stopLoading();
				}
				
				close();
				
				FbDialog.this.dismiss();
				if (mSpinner != null) {
					mSpinner.dismiss();
				}
				mListener.onTimeout();
			}
		}
	};
	
	public void setTypeface(Typeface tf) {
		if(mSpinner != null && mSpinner instanceof OhProgressDialog) {
			((OhProgressDialog) mSpinner).setTypeface(tf);
		}
	}

}
